package com.example.controller;

import com.example.entity.RestBean;
import com.example.entity.vo.request.EmailRegisterVo;
import com.example.entity.vo.request.ResetAccountPasswordVo;
import com.example.entity.vo.request.ResetCodeConfirmVo;
import com.example.service.AccountService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Pattern;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.function.Supplier;

//验证相关接口

//接口校验
@Validated
@RestController
@RequestMapping("/api/auth")
public class AuthorizeController {

    @Resource
    private AccountService accountService;

    /**
     * 请求邮箱验证码
     * @param email 用户邮箱
     * @param type 请求类型：注册or重置
     * @param request 用于获取用户的IP
     * @return RestBean
     */
    @GetMapping("/ask-code")
    public RestBean<Void> askVerifyCode(
            @RequestParam @Email String email,
            @RequestParam @Pattern(regexp = "(register|reset)") String type,
            HttpServletRequest request
    ) {
        String message = accountService.registerEmailVerifyCode(type,email,request.getRemoteHost());
        if(message == null){
            //没有错误信息，表示可以正常发送
            //并且，已经将用户的请求信息放进了消息队列，将生成的对应的验证码存放在redis
            return RestBean.success();
        }else {
            return RestBean.failure(400,message);
        }
    }

    /**
     * 进行用户注册操作，需要先请求邮件验证码
     * @param vo 注册信息
     * @return 是否注册成功
     */
    @PostMapping("/register")
    public RestBean<Void> register(@RequestBody @Valid EmailRegisterVo vo){
        return this.messageHandle(() ->
                accountService.registerEmailAccount(vo));
    }

    /*重置密码*/
    /*用户带着验证码请求对应接口，然后后端仅对验证码是否正确进行验证，用户填写新的密码
之后，请求重置密码接口，不仅需要带上密码还要之前的验证码一起，然后再次验证验证码
如果正确，就重置密码*/

    /**
     * 确认邮箱验证码
     * @param vo 邮箱和验证码
     * @return 结果信息
     */
    @PostMapping("/reset-confirm")
    public RestBean<Void> resetCodeConfirm(@RequestBody @Valid ResetCodeConfirmVo vo){
        return this.messageHandle(()->
            accountService.resetCodeConfirm(vo)
        );
    }

    /**
     * 再次验证验证码，并更账户新密码
     * @param vo 邮箱、验证码、新密码
     * @return 更新结果
     */
    @PostMapping("/reset-password")
    public RestBean<Void> resetAccountPassword(@RequestBody @Valid ResetAccountPasswordVo vo){
        return this.messageHandle(()->
            accountService.resetAccountPassword(vo)
        );
    }

    /**
     * 针对于返回值为String作为错误信息的方法进行统一处理
     * @param action 具体操作
     * @return 响应结果
     * @param <T> 响应结果类型
     */
    private <T> RestBean<T> messageHandle(Supplier<String> action){
        String message = action.get();
        if(message == null)
            return RestBean.success();
        else
            return RestBean.failure(400, message);
    }
}
